const MiniCssExtractPlugin = require("mini-css-extract-plugin"); //提取css的插件
const HtmlWebpackPlugin = require("html-webpack-plugin"); //自动生成html的插件
const WebpackCdnPlugin = require("webpack-cdn-plugin"); //自动生成cdn的插件
const CompressionWebpackPlugin = require("compression-webpack-plugin"); //打包压缩静态资源文件

// 定义需要排除并通过 CDN 加载的模块
const excludeModules = (modules) => {
  // 根据传入的模块生成 externals 配置和 CDN 引用
  const externals = {};
  const cdn = {};

  modules.forEach((module) => {
    externals[module.name] = module.global; // Webpack `externals` 配置
    cdn[module.name] = module.cdnUrl; // CDN 链接
  });

  return { externals, cdn };
};

// 需要排除并通过 CDN 加载的模块配置
const modulesToExclude = [
  // {
  //   name: "react",
  //   global: "React",
  //   cdnUrl:
  //     "https://cdn.jsdelivr.net/npm/react@18.0.0/umd/react.production.min.js",
  // },
  // {
  //   name: "react-dom",
  //   global: "ReactDOM",
  //   cdnUrl:
  //     "https://cdn.jsdelivr.net/npm/react-dom@18.0.0/umd/react-dom.production.min.js",
  // },
  {
    name: "lodash", // 排除的依赖库的名称
    global: "_", // 从 CDN 地址请求下来的 js 中提供对应的名称
    cdnUrl: "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js",
  },
  // 可以继续添加其他模块
];

// 获取 Webpack 外部配置和 CDN 配置
const { externals, cdn } = excludeModules(modulesToExclude);

module.exports = {
  plugins: [
    new HtmlWebpackPlugin({
      filename: "index.html",
      template: "src/index.html",
      title: "prod 模式",
      minify: {
        // 压缩HTML文件
        removeComments: true, // 移除HTML中的注释
        collapseWhitespace: true, // 删除空白符与换行符
        minifyCSS: true, // 压缩内联css
      },
      inject: "body",
      // 在生产环境下注入 CDN 链接
      cdn: cdn,
    }),
    // new WebpackCdnPlugin({
    //   modules: [
    //     {
    //       name: "lodash",
    //       var: "_",
    //       path: "https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js",
    //     },
    //     // 添加其他需要从CDN加载的静态资源
    //   ],
    //   publicPath: "/",
    // }),
    // 注意： MiniCssExtractPlugin 推荐只用于生产环境，因为该插件在开发环境下会导致HMR功能缺失，所以日常开发中，还是用style-loader。
    //提取css成单独文件
    new MiniCssExtractPlugin({
      //对输出的文件重命名，如果不写则建立在项目build下，名称为 main.css
      filename: "asset/css/[name].[contenthash:8].css", // 启动长期缓存。根据需要添加 [name]
      chunkFilename: "asset/css/[id].[contenthash:8].css",
    }),
    // 生产打包时，启用 gzip 预压缩静态文件
    // https://webpack.docschina.org/plugins/compression-webpack-plugin/#getting-started
    new CompressionWebpackPlugin({
      // filename: '[path].gz[query]',
      // algorithm: 'gzip', //压缩算法
      // test: /\.js$|\.css$|\.html$/,
      // threshold: 10240, // //压缩超过此大小的文件,以字节为单位
      // minRatio: 0.8,
      // deleteOriginalAssets: false, //删除原始文件只保留压缩后的文件
      filename: "[path][base].gz",
      algorithm: "gzip", //压缩算法
      test: /\.js$|\.html$|\.css$/,
      threshold: 1, //压缩超过此大小的文件,以字节为单位,因为是 demo 项目文件都比较小，所以把 threshold: 1
      minRatio: 0.8,
      exclude: /node_modules/,
      deleteOriginalAssets: false, //删除原始文件只保留压缩后的文件
    }),
  ],
  externals: externals,
};
